from sklearn import datasets
import numpy as np
def knn(x_tr,y_tr,x_te,y_te,k):
    lable = []#lable数组用来记录训练
    #计算测试集与训练集的距离
    for i in range(len(y_te)):
        distances = np.linalg.norm(x_tr - x_te[i], axis=1, ord=2)#平方和的根号
        #求出距离从小到大的索引值
        ind = np.argsort(distances)
        count = np.zeros(3)#3的原因是数据集分类只有3个
        for j in range(k):
            #根据距离的索引值，找到训练组的类别y_tr[index]也就是训练集中离测试样本最近的点的类别，然后根据类别为索引值在count数组里加一
            index = ind[j]
            t = y_tr[index]
            count[t] += 1

        #求出count数组中最大的值的索引值，该索引值也就是分类的类别，并将其加入到label里
        index1 = np.argsort(count)[::-1]
        lable.append(index1[0])#index1中第一列为测试集中统计最多的类别
    #判断label和测试集中的特征是否一致

    d = (lable == y_te)
    score = np.sum(d) / len(y_te)#计算得分

    return score

#主函数采取的是以数据集的75%为训练集，25为测试集
data = datasets.load_iris()
X = data.data
y = data.target
#训练集
ind = np.random.randint(1, len(y), round(len(y) * 0.75))
X_train = X[ind, :]
y_train = y[ind]
#测试集
ind = np.random.randint(1, len(y), round(len(y) * 0.25))
X_test = X[ind, :]
y_test = y[ind]
print('当k = 1时，knn的精度为：',knn(X_train,y_train,X_test,y_test,k = 1))
print('当k = 3时，knn的精度为：',knn(X_train,y_train,X_test,y_test,k = 3))
print('当k = 5时，knn的精度为：',knn(X_train,y_train,X_test,y_test,k = 5))
print('当k = 7时，knn的精度为：',knn(X_train,y_train,X_test,y_test,k = 7))
